#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include<pthread.h>



#define SERVER_PORT 8080    //服务器端口号

//int client_socks[2] = {4, 5};    // 存储客户端套接字描述符

int clientNum = 0;  //客户端总数
int requestNum;  //总请求次数

#define MAX_THREADS 100     // 线程池的最大容量
#define BUFFER_SIZE 1024    // 缓冲区大小

// 消息队列
Queue messageQueue;

// 线程池
pthread_t threadPool[MAX_THREADS];
int threadCount = 0;  // 当前线程池中的线程数

// 互斥锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

typedef struct {
    int x; // 棋子横坐标   x和y为相对于棋盘的坐标。最左上角为（0，0）
    int y; // 棋子纵坐标
    int kind; // 棋子种类 0为黑，1为白,其余为无
} ChessPiece;
ChessPiece chessPieces[365];  //定义一个存储棋子信息的结构体。大小设置得比实际19×19=361大一些

typedef struct{
    int x;
    int y;
    int kind;
    int circumstance;  //某个棋子的状态 0：待判断，1：依靠周围的棋子活
}ChessToJudge;  //暂时用来判断棋子死活的结构体。里面装的是暂时需要判断死活的一片棋子
ChessToJudge chessToJudge[365];  //记得每次判断之后暂时清空

// 定义队列节点
typedef struct QueueNode {
    int data;
    struct QueueNode* next;
} QueueNode;

// 定义队列
typedef struct {
    QueueNode* front;  // 队列头部
    QueueNode* rear;   // 队列尾部
    int size;          // 队列大小
} Queue;

// 初始化队列
void initQueue(Queue* q) {
    q->front = q->rear = NULL;
    q->size = 0;
}

// 判断队列是否为空
int isEmpty(Queue* q) {
    return (q->front == NULL);
}

// 入队
void enqueue(Queue* q, int data) {
    QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
    if (!newNode) {
        perror("内存分配失败");
        exit(EXIT_FAILURE);
    }
    newNode->data = data;
    newNode->next = NULL;

    if (isEmpty(q)) {
        q->front = q->rear = newNode;
    }
    else {
        q->rear->next = newNode;
        q->rear = newNode;
    }
    q->size++;
}

// 出队
int dequeue(Queue* q) {
    if (isEmpty(q)) {
        fprintf(stderr, "队列为空\n");
        exit(EXIT_FAILURE);
    }

    QueueNode* temp = q->front;
    int data = temp->data;
    q->front = q->front->next;

    if (q->front == NULL) {
        q->rear = NULL;
    }

    free(temp);
    q->size--;
    return data;
}

// 获取队列大小
int queueSize(Queue* q) {
    return q->size;
}

void* threadPoolWorker(void* arg) {

    while (1) {
        pthread_mutex_lock(&mutex);

        // 等待消息队列中有足够的请求
        while (queueSize(&messageQueue) < 2) {
            pthread_cond_wait(&cond, &mutex);
        }

        // 从消息队列中取出两个请求
        int client1 = dequeue(&messageQueue);
        int client2 = dequeue(&messageQueue);

        pthread_mutex_unlock(&mutex);

        // 建立连接并处理
        client_socks[0] = client1;
        client_socks[1] = client2;

        pthread_t thread;
        pthread_create(&thread, NULL, handleClient, (void*)&client_socks[0]);
        pthread_detach(thread);

        pthread_create(&thread, NULL, handleClient, (void*)&client_socks[1]);
        pthread_detach(thread);
    }
}


void* handleClient(void* arg) {
    int client_sock = *(int*)arg;  // 将 void* 类型的参数转换回 int 类型
    char buf[BUFFER_SIZE];  // 读取字符长度

    printf("一个独立的客户端线程已创建,其socket为：%d\n", client_sock);
    printf("此时同时在线的用户数为：：%d\n", clientNum);

        // 处理游戏逻辑
        while (1) {  //接收并转发消息，直到没有更多消息或出现错误

            len = read(client_sock, buf, sizeof(buf) - 1);  //接收客户端信息
            buf[len] = '\0';
            printf("收到的字符串长度和内容：[%d]: %s\n", len, buf);

            printf("套接字为：%d\n", client_sock);

            requestNum = requestNum + 1; //总请求数加1
            printf("当前接收到总请求数为：%d\n", requestNum);


            if (clientNum < 2) {  //客户端总数不到2，只读数据，不传数据。不处理数据。

                printf("当前已加入的客户端socket为：%d等待另一位玩家加入\n", client_sock);

            }
            else {  //客户端总数已达2，可以考虑开始下棋

                int enemy_sock;  //对方的socket

                if (client_sock == client_socks[0]) {
                    enemy_sock = client_socks[1];
                }
                else {
                    enemy_sock = client_socks[0];
                }

                int black_score, white_score, result;
                if (requestNum == 42) {    //演示用。双方各走20步，直接判断输赢。

                    calculate_score(chessPieces, &black_score, &white_score, &result);
                }
                if (1 == result) {  //黑胜
                    write(enemy_sock, "5050", len);   //代表某一方胜利的数字
                    write(client_sock, "5050", len);
                    printf("黑棋已获胜\n");
                    break;    //传递完立刻退出循环，不继续传递信息
                }
                else {   //白胜
                    write(enemy_sock, "6060", len);
                    write(client_sock, "6060", len);
                    printf("白棋已获胜\n");
                    break;
                }

                len = write(enemy_sock, buf, len);  //读什么就写什么。但是写到另一个客户端socket里

                printf("已经向socket为%d的客户端传递返回内容：%s\n", enemy_sock, buf);



                int xInt = -1;
                int yInt = -1;
                int kind = -1;
                changeStoI(buf, &xInt, &yInt);  //从buf中获取int型的xy坐标

                if (client_sock = client_socks[0]) {  //当前为黑棋
                    addChess(xInt, yInt, 0);  //加入黑棋
                }
                else {
                    addChess(xInt, yInt, 1);  //加入白棋
                }

                printf("已将数组内加入如下棋子: %d,%d,0\n", xInt, yInt);
                printf("开始处理吃子问题\n");
                changeForThisStep(xInt, yInt, kind);
                printf("已处理吃子问题\n");

            }

            memset(buf, 0, sizeof(buf));  //清除缓冲区之前的内容
        write(enemy_sock, buf, len);  // 将消息发送给另一个客户端

        memset(buf, 0, sizeof(buf));  // 清除缓冲区之前的内容
    }

    close(client_sock);  // 完成后关闭与该客户端的连接
    pthread_exit(NULL);
}

void initChessPieces() {// 初始化棋子数组（初始化内容均为-1，代表该位置无有效棋子）  x和y为相对于棋盘的坐标
    int i;
    for (i = 0; i < 365; i++) {
        chessPieces[i].x = -1;
        chessPieces[i].y = -1;
        chessPieces[i].kind = -1;
    }
    printf("已初始化棋子数组\n");
}

void addChess(int x, int y, int kind) {  //在某方落子的时候，向棋子数组内添加新的棋子（有效棋子）  x和y为相对于棋盘的坐标
    int i;
    for (i = 0; i < 365; i++) {
        if (chessPieces[i].x == -1 && chessPieces[i].y == -1 && chessPieces[i].kind == -1) { //从头找，找到一个没有棋子的位置
            chessPieces[i].x = x;
            chessPieces[i].y = y;
            chessPieces[i].kind = kind ;
            printf("已向数组添加新棋子，坐标为:");
            printf("%d,%d,%d\n",x,y,kind);
            break;
        }
    }
}

void delChess(int x, int y){  //某个棋子死，在数组中把它重置掉  x和y为相对于棋盘的坐标
    int i;
    for (i = 0; i < 365; i++) {
        if (chessPieces[i].x == x && chessPieces[i].y == y) { //从头找，找到该棋子
            chessPieces[i].x = -1;
            chessPieces[i].y = -1;
            chessPieces[i].kind = -1 ;
            printf("该棋子已死，坐标为:\");\n"
                   "            printf(\"%d,%d,%d\\n",x,y);
            break;
        }
    }
}



void changeItoS(int a, int b, char result[]) {  //将坐标转化为字符串
    char str_a[3], str_b[3];

    sprintf(str_a, "%02d", a);  // 将a和b转换为字符串，并添加前导零（如果需要）
    sprintf(str_b, "%02d", b);

    result[0]=str_a[0];
    result[1]=str_a[1];
    result[2]=str_b[0];
    result[3]=str_b[1];
    result[4] = '\0'; // 添加字符串结束符
}

void changeStoI(char c[], int *num1, int *num2) {  //将字符串转化为坐标

    *num1 = (c[0] - '0') * 10 + (c[1] - '0'); // 直接转换前两个字符

    *num2 = (c[2] - '0') * 10 + (c[3] - '0'); // 直接转换后两个字符
}

int count_liberties(int x, int y, ChessPiece *chessPieces) {  // 计算某一点周围的有效棋子数量
    int liberties = 0;
    for (int dx = -1; dx <= 1; ++dx) {
        for (int dy = -1; dy <= 1; ++dy) {
            if (dx == 0 && dy == 0) continue; // 不检查自己
            int nx = x + dx, ny = y + dy;
            if (nx >= 0 && nx < 19 && ny >= 0 && ny < 19) {
                if (chessPieces[ny * 19 + nx].kind != chessPieces[y * 19 + x].kind) { // 如果是空位或对方棋子
                    liberties++;
                }
            }
        }
    }
    return liberties;
}

void calculate_score(ChessPiece *chessPieces, int *black_score, int *white_score, int *result) {   // 计算黑白棋各自的目数,返回结果
    int black_liberties = 0, white_liberties = 0;
    int black_stones = 0, white_stones = 0;

    for (int i = 0; i < 361; ++i) {
        ChessPiece cp = chessPieces[i];
        if (cp.kind == 0) { // 黑棋
            black_stones++;
            black_liberties += count_liberties(cp.x, cp.y, chessPieces);
        } else if (cp.kind == 1) { // 白棋
            white_stones++;
            white_liberties += count_liberties(cp.x, cp.y, chessPieces);
        }
    }


    *black_score = black_stones;
    *white_score = white_stones;

    if (*black_score - *white_score >= 6.5) {  // 判断胜负
        *result = 1;
    } else {
        *result = 2;
    }
}

void initChessArray(ChessToJudge *array, int size) {  //传进来一个数组，内容全变-1
    int i = 0;
    for (i; i < size; ++i) {
        array[i].x = -1;
        array[i].y = -1;
        array[i].kind = -1;
        array[i].circumstance = -1;
    }
}

void initChessToJudge() {// 初始化或者说清空存储需要判断死活的棋子的数组（初始化内容均为-1，代表该位置无有效棋子）  x和y为相对于棋盘的坐标
    int i;
    for (i = 0; i < 365; i++) {
        chessToJudge[i].x = -1;
        chessToJudge[i].y = -1;
        chessToJudge[i].kind = -1;
        chessToJudge[i].circumstance = -1;
    }
}

void delChessFromArray(ChessToJudge *array, int size){   //传入数组，删除棋子

    int i = 0;
    for (i; i < size; ++i) {
        if(array[i].x != -1 && array[i].y != -1){
            delChess(array[i].x , array[i].y);
        }
    }

}

void addDifferentChessToStruct(int x, int y,int kind){  //判断结构体数组内是否有在这个位置的棋子，如果没有则加入
    int i = 0;
    int haveOrNot = 0;
    for(i;i<sizeof(chessToJudge);i++) {
        if (chessToJudge[i].x == x && chessToJudge[i].y == y) {  //已经有了
            haveOrNot = 1;
            break; //退出循环
        }
    }

    if(haveOrNot == 0){
        int j = 0;
        for(j;j<sizeof(chessToJudge);j++){  //从头找，找到一个还没放棋子的地方，给加进去
            if(-1==chessToJudge[i].x && -1==chessToJudge[i].y){
                chessToJudge[i].x = x;
                chessToJudge[i].y = y;
                chessToJudge[i].kind = kind;
                chessToJudge[i].circumstance = 0; //刚加进去没判断的时候是0
            }else{
                printf("报错：临时存储判断死活棋子的结构体数组chessToJudge已满，请检查问题\n");
            }
        }
    }

}

int enemyOrFriend(int x , int y , int myKind){  //判断座标处状态 传递内容为需要判断的地方的坐标。kind为当前棋子自己的类别

    int i = 0;  //用于循环
    int condition = 0;  //返回值。表示该座标处状态 0为空（有气，直接活），1为同色（需要继续判断同色棋），2为异色或边界（这两种情况都是没气的）
    int enemyKind = -1;  //传入棋子kind的敌对方kind
    if(myKind == 0){
        enemyKind = 1;
    }else{
        enemyKind = 0;
    }

    if( x<=0 || y<=0 || x>=18 || y>=18) {   //是边界

        condition = 2;

    }else{

        for(i; i<sizeof(chessPieces); i++){    //开始判断座标处状态

             if (chessPieces[i].kind == enemyKind &&  x == chessPieces[i].x && y == chessPieces[i].y){  //座标处异色棋

                 condition = 2;
                break;

            }else if(chessPieces[i].kind == myKind &&  x == chessPieces[i].x && y == chessPieces[i].y){  //同色棋

                condition = 1;
                break;

            }else{  //该位置没有棋子

                condition = 0;
                break;
            }
        }
    }

    return condition;

}

void judgeDieorNot(int *dieOrNot){  //判断（由某个棋子开始的）结构体内，一个/一片棋子的死活  （刚传进来的时候，数组内只有一个状态0的棋子） int变量0是活，1是死

    int i = 0;  //循环
    *dieOrNot = 1;  //先假设这片棋是死的
    for(i ; i<sizeof(chessToJudge) ; i++){

        if(chessToJudge[i].circumstance == 0){  //数组中有待判断的棋子
            int thisX = chessToJudge[i].x;  //当前要判断的棋子坐标和种类
            int thisY = chessToJudge[i].y;
            int thisKind = chessToJudge[i].kind;
            int up = enemyOrFriend(thisX , (thisY-1) , thisKind);   //对该棋子上下左右的坐标进行判断
            int down = enemyOrFriend(thisX , (thisY+1) , thisKind);
            int left = enemyOrFriend((thisX-1) , thisY , thisKind);
            int right = enemyOrFriend((thisX+1) , (thisY-1) , thisKind);

            if(2==up && 2==down && 2==left &&2==right){  //仅仅适用于单个棋子的情况。全是2，这个棋其实已经死掉了
                chessToJudge[i].circumstance = 1;  //这个子自己活不了（其实是这个单子已经死了）
                break;
            }else{
                if(0==up || 0==down || 0==left || 0==right){  //周围有气，这块棋直接活了,也不用继续判断了

                    *dieOrNot = 0;
                    initChessToJudge();  //再次把判断用的棋子数组清零。这样当函数返回值是0的时候，调用它的函数可以直接得到一个初始化的、没有任何棋子内容的数组，来表示没有相关棋子死亡
                    break;

                }else{   //周围除了异色、边界只有同色。那就找到所有同色，然后把数组中还没有的坐标加入数组,并把自己的状态设为1（已经判断完了，自己活不了，靠别人活）。当某片死棋只剩下最后一个这样的棋需要判断时，判断完了以后这个结构体数组就没有新添加了。等到下次循环的时候，这片棋就直接判断为死
                  if(1==up){
                      addDifferentChessToStruct(thisX,(thisY-1),thisKind);
                  }
                  if(1==down){
                      addDifferentChessToStruct(thisX,(thisY+1),thisKind);
                  }
                  if(1==left){
                      addDifferentChessToStruct((thisX-1),thisY,thisKind);
                  }
                  if(i==right){
                      addDifferentChessToStruct((thisX+1),thisY,thisKind);
                  }
                  chessToJudge[i].circumstance = 1; //把自己设置为已判断
                }
            }
        }
        }//如果运行到这个for循环结束的地方，还没有跳出循环，说明结构体数组中已经没有能自己活的棋了
    }


int changeForThisPoint(int x , int y , int kind){  //给出由当前这一个点的变化 返回这个棋子组死没死。死就是1，没死是0


    int dieOrNot = 0;  //假设这片棋死没死
    initChessToJudge();  //初始化判断用的结构体数组
    chessToJudge[0].x = x;  //把这个要判断的坐标加入结构体第一号
    chessToJudge[0].y = y;
    chessToJudge[0].kind = kind;
    chessToJudge[0].circumstance = 0;
    judgeDieorNot(&dieOrNot);
    return dieOrNot;
}

void changeForThisStep(int x,int y,int kind){  //处理新下的这一步棋所带来的变化


    int i =0; //循环

    ChessToJudge arraySelf[365];  //把现在的判断数组中的内容赋值给刚建立的数组。如果这个棋子是活的，那么这个结构体数组所有变量都是-1.如果暂时判定死亡，则这个数组中是有实际内容的
    ChessToJudge arrayUp[365];
    ChessToJudge arrayDown[365];
    ChessToJudge arrayRight[365];
    ChessToJudge arrayLeft[365];
    initChessArray(arraySelf , 365);  //初始化这些结构体内容为-1
    initChessArray(arrayUp , 365);
    initChessArray(arrayDown , 365);
    initChessArray(arrayLeft , 365);
    initChessArray(arrayRight , 365);



    int selfKind = kind;  //初始化自己和上下左右棋子的颜色种类。默认和自己相同
    int enemykind = -1;
    int upKind = -1;
    int downKind = -1;
    int rightKind = -1;
    int leftKind = -1;

    int selfDieOrNot = 0;  //初始化自己和上下左右死没死。0是没死，1是死。默认没死
    int upDieOrNot = 0;
    int downDieOrNot = 0;
    int leftDieOrNot = 0;
    int rightDieOrNot = 0;

    if(0==kind){
        enemykind=1;
    }else{enemykind=0;}


    if(x>0 && x<18 && y>0) {  //这步棋上边不为边界
        if(2==enemyOrFriend(x,y-1,kind)){   //如果上方有敌方棋子
            upKind = enemykind;
        }else if(1==enemyOrFriend(x,y-1,kind)){
            upKind = kind;
        }
    }
    if(x>0 && x<18 && y<18){  //这步棋下边不为边界
        if(2==enemyOrFriend(x,y+1,kind)){   //如果上方有敌方棋子
            downKind = enemykind;
        }else if(1==enemyOrFriend(x,y+1,kind)){
            downKind = kind;
        }
    }
    if(y>0 && y<18 && x>0) {  //这步棋右边不为边界
        if(2==enemyOrFriend(x+1,y,kind)){   //如果上方有敌方棋子
            rightKind = enemykind;
        }else if(1==enemyOrFriend(x+1,y,kind)){
            rightKind = kind;
        }
    }
    if(y>0 &&y<18 && x<18) {  //这步棋左边不为边界
        if(2==enemyOrFriend(x-1,y,kind)){   //如果上方有敌方棋子
            leftKind = enemykind;
        }else if(1==enemyOrFriend(x-1,y,kind)){
            leftKind = kind;
        }
    }  //上述4个if结束后，可确定棋子上下左右的情况。空或边界kind为-1，余下kind为实际kind

     selfDieOrNot = changeForThisPoint(x,y,selfKind);  //给有东西的棋子判断死活，然后得到数组 0是没死，1是死
    for (i; i < 365; ++i) {  //循环给它赋值。没再自定义函数，已经比较多了，怕分不清
        arraySelf[i].x = chessToJudge[i].x;
        arraySelf[i].y = chessToJudge[i].y;
        arraySelf[i].kind = chessToJudge[i].kind;
        arraySelf[i].circumstance = chessToJudge[i].circumstance;
    }
     if(upKind != -1){
         upDieOrNot = changeForThisPoint(x,y-1,upKind);
         for (i ; i < 365; ++i) {
             arrayUp[i].x = chessToJudge[i].x;
             arrayUp[i].y = chessToJudge[i].y;
             arrayUp[i].kind = chessToJudge[i].kind;
             arrayUp[i].circumstance = chessToJudge[i].circumstance;
         }
     }
     if(downKind != -1){
        downDieOrNot = changeForThisPoint(x,y+1,downKind);
        for (i; i < 365; ++i) {  //循环给它赋值。没再自定义函数，已经比较多了，怕分不清
            arrayDown[i].x = chessToJudge[i].x;
            arrayDown[i].y = chessToJudge[i].y;
            arrayDown[i].kind = chessToJudge[i].kind;
            arrayDown[i].circumstance = chessToJudge[i].circumstance;
        }
    }
    if(leftKind != -1){
        leftDieOrNot = changeForThisPoint(x-1,y,leftKind);
        for (i; i < 365; ++i) {  //循环给它赋值。没再自定义函数，已经比较多了，怕分不清
            arrayLeft[i].x = chessToJudge[i].x;
            arrayLeft[i].y = chessToJudge[i].y;
            arrayLeft[i].kind = chessToJudge[i].kind;
            arrayLeft[i].circumstance = chessToJudge[i].circumstance;
        }
    }if(rightKind != -1){
        rightDieOrNot = changeForThisPoint(x+1,y,rightKind);
        for (i; i < 365; ++i) {  //循环给它赋值。没再自定义函数，已经比较多了，怕分不清
            arrayRight[i].x = chessToJudge[i].x;
            arrayRight[i].y = chessToJudge[i].y;
            arrayRight[i].kind = chessToJudge[i].kind;
            arrayRight[i].circumstance = chessToJudge[i].circumstance;
        }
    }  //到这里，死掉的数组也已经被赋值了

    int totalDeath = selfDieOrNot+upDieOrNot+downDieOrNot+leftDieOrNot+rightDieOrNot;
    if(0==totalDeath){
        printf("这一步没有棋子死掉\n");
    }else if(1==totalDeath){  //只死了一处
        if(selfDieOrNot == 1){
            delChessFromArray(arraySelf,365);
        }
        if(upDieOrNot == 1){
            delChessFromArray(arrayUp,365);
        }
        if(downDieOrNot == 1){
            delChessFromArray(arrayDown,365);
        }
        if(leftDieOrNot == 1){
            delChessFromArray(arrayLeft,365);
        }
        if(rightDieOrNot == 1){
            delChessFromArray(arrayRight,365);
        }
    }else{  //死了好几处  谁跟这一步的棋一个颜色谁不死

        if(upDieOrNot == 1 && upKind != selfKind){
            delChessFromArray(arrayUp,365);
        }
        if(downDieOrNot == 1 && downKind != selfKind){
            delChessFromArray(arrayDown,365);
        }
        if(leftDieOrNot == 1 && leftKind != selfKind){
            delChessFromArray(arrayLeft,365);
        }
        if(rightDieOrNot == 1 && rightKind != selfKind){
            delChessFromArray(arrayRight,365);
        }
    }


}

void *handleClient(void *arg){  //客户端的线程

    int client_sock = *(int*) arg;  // 将 void* 类型的参数转换回 int 类型
    int len;
    char buf[1024];  // 读取字符长度

        printf("一个独立的客户端线程已创建,其socket为：%d\n",client_sock);
        printf("此时同时在线的用户数为：：%d\n",clientNum);




        while (1) {  // 循环接收并转发消息，直到没有更多消息或出现错误

            len = read(client_sock, buf, sizeof(buf)-1);  //接收客户端信息
            buf[len] = '\0';
            printf("收到的字符串长度和内容：[%d]: %s\n", len, buf);

            printf("套接字为：%d\n",client_sock);

            requestNum = requestNum +1; //总请求数加1
            printf("当前接收到总请求数为：%d\n",requestNum);


            if(clientNum <2){  //客户端总数不到2，只读数据，不传数据。不处理数据。

                printf("当前已加入的客户端socket为：%d等待另一位玩家加入\n",client_sock);

            }else {  //客户端总数已达2，可以考虑开始下棋

                    int enemy_sock;  //对方的socket

                    if (client_sock == client_socks[0]) {
                        enemy_sock = client_socks[1];
                    } else {
                        enemy_sock = client_socks[0];
                    }

                int black_score, white_score, result;
                if(requestNum == 42) {    //演示用。双方各走20步，直接判断输赢。

                    calculate_score(chessPieces, &black_score, &white_score, &result);
                }
                if(1==result){  //黑胜
                    write(enemy_sock, "5050", len);   //代表某一方胜利的数字
                    write(client_sock, "5050", len);
                    printf("黑棋已获胜\n");
                    break;    //传递完立刻退出循环，不继续传递信息
                }else{   //白胜
                    write(enemy_sock, "6060", len);
                    write(client_sock, "6060", len);
                    printf("白棋已获胜\n");
                    break;
                      }

                    len = write(enemy_sock, buf, len);  //读什么就写什么。但是写到另一个客户端socket里

                    printf("已经向socket为%d的客户端传递返回内容：%s\n", enemy_sock,buf);



                    int xInt = -1;
                    int yInt = -1;
                    int kind = -1;
                    changeStoI(buf, &xInt, &yInt);  //从buf中获取int型的xy坐标

                    if(client_sock = client_socks[0]){  //当前为黑棋
                        addChess(xInt,yInt,0);  //加入黑棋
                    }else{
                        addChess(xInt,yInt,1);  //加入白棋
                    }

                    printf("已将数组内加入如下棋子: %d,%d,0\n", xInt,yInt);
                    printf("开始处理吃子问题\n");
                    changeForThisStep(xInt,yInt,kind);
                    printf("已处理吃子问题\n");

            }

            memset(buf, 0, sizeof(buf));  //清除缓冲区之前的内容

        }




    close(client_sock); // 完成后关闭与该客户端的连接

}


int main(void) {
    int sock;   // 服务器的sock
    struct sockaddr_in server_addr;

    sock = socket(AF_INET, SOCK_STREAM, 0);  // 创建套接字
    if (sock < 0) {
        perror("socket()出错");
        return 1;
    }

    bzero(&server_addr, sizeof(server_addr));  // 将创建后里面可能存在的乱码给清零

    server_addr.sin_family = AF_INET;    // 指的是服务器地址，它是一个用于标识服务器在网络中的位置的地址
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(SERVER_PORT);

    if (bind(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("bind()出错");
        close(sock);
        return 1;
    }

    if (listen(sock, 128) < 0) {
        perror("listen()出错");
        close(sock);
        return 1;
    }

    printf("等待客户端的连接\n");

    // 初始化消息队列
    initQueue(&messageQueue);

    // 初始化线程池
    for (int i = 0; i < MAX_THREADS; ++i) {
        pthread_create(&threadPool[i], NULL, threadPoolWorker, NULL);
        threadCount++;
    }

    while (1) {
        struct sockaddr_in client;
        socklen_t client_addr_len = sizeof(client);
        int new_client_sock = accept(sock, (struct sockaddr*)&client, &client_addr_len);

        if (new_client_sock != -1) {
            char client_ip[64];
            inet_ntop(AF_INET, &client.sin_addr.s_addr, client_ip, sizeof(client_ip));
            printf("客户端ip为: %s\t 端口 : %d\n", client_ip, ntohs(client.sin_port));

            // 将新客户端加入消息队列
            pthread_mutex_lock(&mutex);
            enqueue(&messageQueue, new_client_sock);
            pthread_cond_signal(&cond);
            pthread_mutex_unlock(&mutex);

            clientNum++;
        }
        else {
            perror("accept()出错");
        }
    }

    // 关闭监听套接字和其他资源
    close(sock);

    return 0;

}